#ifndef __SG_PCL_DOWNSAMPLE_H__
#define __SG_PCL_DOWNSAMPLE_H__

#include "SGPCLJsonConfig.h"

#include <filesystem>
#include <string>

#include <pcl/filters/voxel_grid.h>

namespace sgpcl
{

/// <summary>
/// 降采样算法参数
/// </summary>
struct SGDownSampleConfig : public SGPCLJsonConfig
{
  float fVoxelSize; // 体素尺寸

  SGPCL_API SGDownSampleConfig();

  SGPCL_API ~SGDownSampleConfig() = default;

  /// <summary>
  /// 解析Json字符串，读取参数
  /// </summary>
  /// <param name="sJsonRoot">Json节点</param>
  SGPCL_API void ParseJson(const rapidjson::Value& sJsonRoot) final override;
};

/// <summary>
/// 下采样
/// </summary>
/// <typeparam name="PointT">点类型</typeparam>
/// <param name="spCloud">原点云</param>
/// <param name="sConfig">算法参数</param>
/// <returns>降采样结果点云</returns>
template <typename PointT>
typename pcl::PointCloud<PointT>::Ptr DownSample(
  typename pcl::PointCloud<PointT>::ConstPtr spCloud, const SGDownSampleConfig& sConfig)
{
  // 计时器
  //SG_TIMER("降采样");

  // 降采样体素尺寸
  const float fVoxelSize = sConfig.fVoxelSize;

  // 创建ApproximateVoxelGrid体素降采样对象
  pcl::VoxelGrid<PointT> vg;
  vg.setInputCloud(spCloud);
  vg.setLeafSize(fVoxelSize, fVoxelSize, fVoxelSize);

  // 进行滤波处理
  pcl::PointCloud<PointT>::Ptr spDownSample(new pcl::PointCloud<PointT>);
  vg.filter(*spDownSample);

  return spDownSample;
}
}

#endif // !__SG_PCL_DOWNSAMPLE_H__
